package PRO;

import java.math.BigInteger;

public class Fermat {

    // Metodo de factorizacion de fermat
    public BigInteger factor(BigInteger n) {

        BigInteger A = BigMath.raizPiso(n);
        BigInteger Bsq = A.multiply(A).subtract(n);
        BigInteger B = BigMath.raizPiso(Bsq);
        BigInteger AmenosB = A.subtract(B);

        // c es un limite para que el algoritmo se detenga
        BigInteger c = new BigInteger("30");
        BigInteger AmenosB_prev = A.subtract(B).add(c);
        BigInteger resultado = null;

        while (!BigMath.raizPiso(Bsq).pow(2).equals(Bsq) && AmenosB_prev.subtract(AmenosB).compareTo(c) > -1) {
            A = A.add(BigInteger.ONE);
            Bsq = A.multiply(A).subtract(n);

            B = BigMath.raizPiso(Bsq);
            AmenosB_prev = AmenosB;
            AmenosB = A.subtract(B);
        }

        if (BigMath.raizPiso(Bsq).pow(2).equals(Bsq)) {
            resultado = AmenosB;
        } else {
            boolean resuelto = false;
            BigInteger p = AmenosB.add(BigMath.DOS);

            if (p.remainder(BigMath.DOS).intValue() == 0) {
                p = p.add(BigInteger.ONE);
            }
            while (!resuelto) {
                p = p.subtract(BigMath.DOS);

                if (n.remainder(p).equals(BigInteger.ZERO)) {
                    resuelto = true;
                }
            }
            resultado = p;
        }
        return resultado;
    }
}
